<template>
  <div>
    <span @click="onShowDrawer">
      <slot></slot>
    </span>

    <h-drawer v-model="visible" :width="1200" unit="px" :loading="loading">
      <template #title>
        <span v-if="props.workNo" style="font-size: 16px">审核费用</span>
        <span v-else class="add_fee_title">
          <span>新增服务项目</span>
        </span>
      </template>
      <div class="body">
        <div v-if="props.workNo" class="info-list">
          <div class="info-item">
            <div class="label">工单单号:</div>
            <div class="value">{{ props.workNo }}</div>
          </div>
          <div class="info-item">
            <div class="label">审核状态:</div>
            <div class="value">
              <HStatus :height="22" type="warning">待审核</HStatus>
            </div>
          </div>
          <div class="info-item">
            <div class="label">审核备注:</div>
            <div class="value">
              <el-input
                v-model.trim="auditRemark"
                clearable
                maxlength="200"
                placeholder="填写备注信息"
                show-word-limit
                size="small"
                type="textarea"
                resize="both"
              />
            </div>
          </div>
        </div>
        <el-table
          :border="true"
          resizable
          :data="feeList"
          :max-height="700"
          :span-method="cellMerge"
        >
          <!-- 序号 -->
          <el-table-column label="序号" width="50" type="index" fixed="left" :align="'center'" />

          <!-- 费用单号 -->
          <el-table-column v-if="props.workNo" label="费用单号" width="150" prop="feeNo" />

          <!-- 收支类型 -->
          <el-table-column label="结算类型" width="150">
            <template #default="{ row, $index }">
              <el-select
                v-model="row.type"
                placeholder="结算类型"
                filterable
                @change="onChangeIncomeOrPayType($index)"
              >
                <el-option :value="1" label="公司承担"></el-option>
                <el-option :value="2" label="收取客户"></el-option>
                <el-option :value="3" label="支付网点"></el-option>
              </el-select>
            </template>
          </el-table-column>

          <!-- 费用名称 -->
          <el-table-column label="费用名称" width="150" show-overflow-tooltip>
            <template #default="{ row, $index }">
              <el-select
                v-model="row.workFeeProjectId"
                placeholder="请选择"
                filterable
                :filter-method="handleGetFeeProjectOptions"
                :loading="getFeePorjectOptionListLoading"
                remote-show-suffix
                :class="{
                  'validate-fail-select': isEnableTableValidate && !row.workFeeProjectId,
                }"
              >
                <el-option
                  v-for="item in feeProjectOptionList"
                  :key="item.name"
                  :value="item.id"
                  :label="item.name"
                  @click="handleChangeFeeProject(item, $index)"
                />
              </el-select>
            </template>
          </el-table-column>

          <!-- 公里数 -->
          <el-table-column label="公里数" width="160" show-overflow-tooltip>
            <template #default="{ row, $index }">
              <el-input-number
                v-model.trim="row.kilometers"
                placeholder="请输入公里数"
                :min="0"
                :max="999"
                style="width: 120px"
                :controls="false"
                :disabled="!getIsEnableKilometer(row.workFeeProjectId)"
                @change="handleSilometerChange($index)"
              />
            </template>
          </el-table-column>

          <!-- 申请数量 -->
          <el-table-column show-overflow-tooltip label="申请数量" width="160">
            <template #default="{ row, $index }">
              <el-input-number
                v-model.trim="row.qty"
                placeholder="请输入数量"
                :min="1"
                :max="999"
                :controls="false"
                style="width: 120px"
                @change="handleQtyChange($index)"
              />
            </template>
          </el-table-column>

          <!-- 公司承担 -->
          <el-table-column label="公司承担费用" width="180">
            <template #default="{ row, $index }">
              <el-input-number
                v-model.trim="row.price"
                clearable
                style="width: 140px"
                :controls="false"
                :min="0"
                :max="9999.99"
                placeholder="请输入公司承担费用"
                @change="handleFeeChange($index, 'price')"
              />
            </template>
          </el-table-column>

          <!-- 客户承担 -->
          <el-table-column label="收取客户费用" width="180">
            <template #default="{ row, $index }">
              <el-input-number
                v-model.trim="row.customerUndertakePrice"
                clearable
                style="width: 140px"
                :controls="false"
                :min="0"
                :max="9999.99"
                placeholder="请输入收取客户费用"
                @change="handleFeeChange($index, 'customerUndertakePrice')"
              />
            </template>
          </el-table-column>

          <!-- 网点承担 -->
          <el-table-column label="支付网点费用" width="180">
            <template #default="{ row, $index }">
              <el-input-number
                v-model.trim="row.networkUndertakePrice"
                clearable
                style="width: 140px"
                :controls="false"
                :min="0"
                :max="9999.99"
                placeholder="请输入支付网点费用"
                @change="handleFeeChange($index, 'networkUndertakePrice')"
              />
            </template>
          </el-table-column>

          <!-- 备注 -->
          <el-table-column show-overflow-tooltip label="备注" width="240">
            <template #default="{ row }">
              <el-input
                v-model.trim="row.remark"
                clearable
                placeholder="填写备注"
                maxlength="100"
              />
            </template>
          </el-table-column>

          <!-- 附件 -->
          <el-table-column label="附件(最多上传8个)" :width="annexColumnWidth">
            <template #default="{ row, $index }">
              <div class="updata_pic">
                <template v-for="(img, index) in row.images" :key="index">
                  <h-image
                    :preview-src-list="row.images.map((item) => item.image)"
                    :width="60"
                    :height="37.5"
                    fit="scale-down"
                    :src="img.image"
                    :initial-index="index"
                    :padding="2"
                    :mask-btn-gap="3"
                    :show-del-btn="!img.id"
                    @del="handleDelFile($index, index)"
                  />
                </template>
                <h-image
                  v-if="row.images.length < 8"
                  :src="uploadPlaceholderImg"
                  :width="60"
                  :height="37.5"
                  :padding="2"
                >
                  <el-upload
                    action="#"
                    multiple
                    accept="image/*"
                    :auto-upload="false"
                    :show-file-list="false"
                    :on-change="(file: UploadFile) => handleAddFile(file, $index)"
                  >
                    <i class="iconfont icon-img-upload" style="font-size: 24px; color: #fff"></i>
                  </el-upload>
                </h-image>
              </div>
            </template>
          </el-table-column>

          <!--审核状态-->
          <el-table-column
            v-if="props.workNo"
            label="审核"
            width="120"
            fixed="right"
            :align="'center'"
          >
            <template #default="{ row }">
              <el-select v-model="row.status" filterable placeholder="审核状态">
                <el-option :value="2" label="通过"></el-option>
                <el-option :value="3" label="驳回"></el-option>
              </el-select>
            </template>
          </el-table-column>

          <el-table-column v-if="!props.workNo" label="操作" width="100" fixed="right">
            <template #default="{ row, $index }">
              <el-space :size="0" :spacer="spacer">
                <h-link
                  v-if="!row.feeDetailId && feeList.length > 1"
                  type="error"
                  @click="onDelFeeDetail($index)"
                  >删除</h-link
                >
                <h-link v-if="$index === 0" @click="onAddFeeDetail">添加</h-link>
              </el-space>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <template #footer>
        <HButton is-modal type="primary" @click="onSave">保存</HButton>
        <HButton is-modal @click="onClose">取消</HButton>
      </template>
    </h-drawer>
  </div>
</template>

<script lang="ts" setup>
  import { computed, h, ref } from 'vue'
  import { orderAnnexUpload } from '@/api/upload'
  import { UploadFile, ElUpload, ElDivider } from 'element-plus'
  import _ from 'lodash'
  import uploadPlaceholderImg from '@/assets/image/avatar_upload_default.png'
  import { HMessage, HMessageBox } from '@/components/common/message'
  import {
    useFeeCreate,
    useGetFeeByOrderId,
    useFeeMultipleCheck,
    useGetFeePorjectOptionList,
  } from '@/services/pages/order/useOrderDetail'
  import { CellMergeParam, Fee } from './types'

  const {
    checkForm: multipleCheckForm,
    checkLoading: multipleCheckLoading,
    check: multipleCheck,
  } = useFeeMultipleCheck()
  const { feeList: feeListByOrderId, getFeeLoading, getFee: getFeeById } = useGetFeeByOrderId()
  const { createForm, createLoading, create } = useFeeCreate()
  const {
    optionList: feeProjectOptionList,
    getOptionListParam: getFeePorjectOptionListParam,
    getOptionListLoading: getFeePorjectOptionListLoading,
    getOptionList: getFeePorjectOptionList,
  } = useGetFeePorjectOptionList()

  // 如果有传workId就是审核费用，否则就是申请费用
  const props = defineProps({
    workId: {
      type: String,
      default: () => '',
    },
    workNo: {
      type: String,
      default: () => '',
    },
  })

  const emits = defineEmits<{
    (e: 'update'): void
  }>()

  // 审核备注
  const auditRemark = ref('')

  // 间距组件的间隔符
  const spacer = h(ElDivider, {
    direction: 'vertical',
    style: 'display: flex; align-items: center;',
  })

  // 是否开启表格检查
  const isEnableTableValidate = ref(false)

  // 加载
  const loading = computed(() => {
    return (
      getFeeLoading.value ||
      multipleCheckLoading.value ||
      createLoading.value ||
      fileUploadLoading.value
    )
  })

  // 添加费用弹窗显示状态
  const visible = ref(false)

  // 费用列表
  const feeList = ref<Array<Fee>>([])

  // 文件上传加载
  const fileUploadLoading = ref(false)

  // 附件列宽
  const annexColumnWidth = ref(160)

  /**
   * 单元格合并
   */
  const cellMerge = ({ row, columnIndex }: CellMergeParam) => {
    if (columnIndex === 1 && props.workNo) {
      const _feeList = feeList.value.filter((item) => item.feeId === row.feeId)
      const index = _feeList.findIndex((item) => item.feeDetailId === row.feeDetailId)
      if (index === 0) {
        return {
          rowspan: _feeList.length,
          colspan: 1,
        }
      } else {
        return {
          rowspan: 0,
          colspan: 0,
        }
      }
    }
  }

  /**
   * 设置附件列的宽度
   */
  const setAnnexColumnWidth = () => {
    let maxImageLength = Math.max(...feeList.value.map((item) => item.images.length))

    // 在图片数量小于8张时要把上传按钮的宽度计算进去
    if (maxImageLength < 8) {
      maxImageLength += 1
    }

    // 这是为了解决删剩一张图时，列宽会变得很小，导致标题会换行
    if (maxImageLength > 0) {
      annexColumnWidth.value = maxImageLength * 60 + (maxImageLength - 1) * 8 + 24
    }

    if (annexColumnWidth.value < 130) {
      annexColumnWidth.value = 130
    }
  }

  /**
   * 添加费用详情
   */
  function onAddFeeDetail() {
    feeList.value.push({
      delImageIds: [],
      feeId: '',
      images: [],
      networkUndertakePrice: 0,
      price: 0,
      qty: 1,
      customerUndertakePrice: 0,
      remark: '',
      type: 1,
      workFeeProjectId: '',
      kilometers: 0,
      status: 2,
      feeNo: '',
      orderId: props.workId,
      feeDetailId: '',
    })
  }

  /**
   * 费用详情删除
   * @param index - 费用索引
   */
  function onDelFeeDetail(index: number) {
    if (feeList.value.length === 1) {
      return
    }
    feeList.value.splice(index, 1)
  }

  /**
   * 保存按钮点击事件
   */
  const onSave = async () => {
    isEnableTableValidate.value = true
    if (props.workNo) {
      const feeTempObj: Record<string, Array<Fee>> = {}

      for (let i = 0; i < feeList.value.length; i++) {
        const fee = feeList.value[i]
        if (Object.keys(feeTempObj).includes(fee.feeId)) {
          feeTempObj[fee.feeId].push(fee)
        } else {
          feeTempObj[fee.feeId] = [fee]
        }

        if (!fee.workFeeProjectId) {
          HMessageBox.error('请选择费用名称')
          return
        }

        const files = fee.images.filter((item) => !!item.file).map((item) => item.file)
        if (files.length > 0) {
          const res = await orderAnnexUpload(files)
          feeList.value[i].images = feeList.value[i].images.filter((item) => !!item.id)
          res.data.data.rows.forEach((imgUrl) => {
            feeList.value[i].images.push({
              id: null,
              image: imgUrl,
            })
          })
        }
      }

      for (const key in feeTempObj) {
        const fee = feeTempObj[key]
        multipleCheckForm.value.checkVoList.push({
          id: fee[0].feeId,
          remark: auditRemark.value,
          feeDetails: fee.map((item) => {
            return {
              customerUndertakePrice: item.customerUndertakePrice,
              delImageIds: item.delImageIds,
              id: item.feeDetailId,
              images: item.images.map((imgRow) => {
                return {
                  id: imgRow.id,
                  image: imgRow.image,
                }
              }),
              kilometers: item.kilometers,
              networkUndertakePrice: item.networkUndertakePrice,
              price: item.price,
              qty: item.qty,
              remark: item.remark,
              status: item.status,
              type: item.type,
              workFeeProjectId: item.workFeeProjectId,
            }
          }),
        })
      }

      const res = await multipleCheck()
      if (res.code === 20000) {
        HMessage.success('保存成功')
        emits('update')
        visible.value = false
        feeList.value.length = 0
        return
      }
      HMessageBox.error(res.message)
    } else {
      // 创建
      createForm.value = {
        delFeeDetailIds: [],
        feeDetails: feeList.value.map((item) => {
          return {
            customerUndertakePrice: item.customerUndertakePrice,
            delImageIds: item.delImageIds,
            id: item.feeDetailId,
            images: item.images.map((imgRow) => {
              return {
                id: imgRow.id,
                image: imgRow.image,
              }
            }),
            kilometers: item.kilometers,
            networkUndertakePrice: item.networkUndertakePrice,
            price: item.price,
            qty: item.qty,
            remark: item.remark,
            status: item.status,
            type: item.type,
            workFeeProjectId: item.workFeeProjectId,
          }
        }),
        id: '',
        remark: auditRemark.value,
        workId: props.workId,
      }
      const res = await create()
      if (res.code === 20000) {
        HMessage.success('保存成功')
        emits('update')
        visible.value = false
        feeList.value.length = 0
        return
      }
      HMessageBox.error(res.message)
    }
  }

  /**
   * 费用项目选择事件
   * @param {Object} item - 费用项目
   * @param index - 费用索引
   */
  function handleChangeFeeProject(item: OrderFeeProjectOption, index: number) {
    feeList.value[index].customerUndertakePrice = 0
    feeList.value[index].price = 0
    feeList.value[index].networkUndertakePrice = 0
    switch (feeList.value[index].type) {
      case 1:
        feeList.value[index].price = item.price
        break
      case 2:
        feeList.value[index].customerUndertakePrice = item.price
        break
      case 3:
        feeList.value[index].networkUndertakePrice = item.price
        break
    }
  }

  /**
   * 费用项目下拉数据
   */
  const handleGetFeeProjectOptions = _.throttle((query: string) => {
    if (getFeePorjectOptionListParam.value.name !== query) {
      getFeePorjectOptionListParam.value.name = query
      getFeePorjectOptionList()
    }
  }, 600)

  /**
   * 添加图片或pdf
   * @param file - 文件
   * @param index - 费用索引
   */
  const handleAddFile = async (file: UploadFile, index: number) => {
    if (!file.raw.type.includes('image')) {
      HMessageBox.error('只能上传图片类型的文件')
      return
    }
    if (feeList.value[index].images.length >= 8) {
      HMessageBox.error('上传的数量不能超过8个')
      return
    }
    feeList.value[index].images.push({
      file: file.raw,
      image: URL.createObjectURL(file.raw),
      id: '',
    })
    setAnnexColumnWidth()
  }

  /**
   * 删除文件
   * @param index - 费用索引
   * @param imgIndex - 文件索引
   */
  const handleDelFile = (index: number, imgIndex: number) => {
    if (feeList.value[index].images[imgIndex].id) {
      HMessageBox.error('禁止删除原本附件')
      return
    }
    const imgs = feeList.value[index].images.splice(imgIndex, 1)
    feeList.value[index].delImageIds.push(imgs[0].id)
    setAnnexColumnWidth()
  }

  /**
   * 显示申请费用弹窗
   */
  const onShowDrawer = async () => {
    visible.value = true
    getFeePorjectOptionList()
    if (props.workNo) {
      // 批量审核
      await getFeeById(props.workId)
      feeList.value.length = 0
      feeListByOrderId.value.forEach((fee) => {
        fee.feeDetailInfoVos.forEach((feeDetail) => {
          feeList.value.push({
            orderId: props.workId,
            feeId: fee.id,
            delImageIds: [],
            feeDetailId: feeDetail.id,
            images: feeDetail.images.map((img) => {
              return {
                id: img.id,
                image: img.image,
                file: null,
              }
            }),
            networkUndertakePrice: feeDetail.networkUndertakePrice,
            price: feeDetail.price,
            qty: feeDetail.qty,
            customerUndertakePrice: feeDetail.customerUndertakePrice,
            remark: feeDetail.remark,
            type: feeDetail.type,
            workFeeProjectId: feeDetail.workFeeProjectId,
            kilometers: feeDetail.kilometers,
            status: feeDetail.status === 2 || feeDetail.status === 3 ? feeDetail.status : 2,
            feeNo: fee.workFeeNo,
          })
        })
      })
    } else {
      // 创建
      feeList.value = [
        {
          orderId: props.workId,
          feeId: '',
          remark: '',
          delImageIds: [],
          feeDetailId: '',
          images: [],
          networkUndertakePrice: 0,
          price: 0,
          customerUndertakePrice: 0,
          qty: 1,
          kilometers: 0,
          type: 1,
          status: 2,
          workFeeProjectId: '',
          feeNo: '',
        },
      ]
    }

    setAnnexColumnWidth()
  }

  /**
   * 收支类型改变
   * @param index - 费用索引
   */
  const onChangeIncomeOrPayType = (index: number) => {
    // 提取费用项目的金额
    let price = 0
    const feeDetail = feeList.value[index]
    if (feeDetail.workFeeProjectId) {
      const feeProject = feeProjectOptionList.value.find(
        (feeProject) => feeProject.id === feeDetail.workFeeProjectId,
      )
      if (feeProject) {
        price = feeProject.price
      }
    }
    feeList.value[index].customerUndertakePrice = 0
    feeList.value[index].price = 0
    feeList.value[index].networkUndertakePrice = 0
    switch (feeDetail.type) {
      case 1:
        feeList.value[index].price = price
        break
      case 2:
        feeList.value[index].customerUndertakePrice = price
        break
      case 3:
        feeList.value[index].networkUndertakePrice = price
        break
    }
  }

  /**
   * 关闭事件
   */
  const onClose = () => {
    feeList.value.length = 0
    visible.value = false
  }

  /**
   * 根据费用id获取费用使用开启公里数
   */
  const getIsEnableKilometer = (feeId: string) => {
    const fee = feeProjectOptionList.value.find((feeProject) => feeProject.id === feeId)
    if (!fee) {
      return false
    }
    return fee.enableRemoteFees
  }

  /**
   * 公里数更新事件
   * @param index - 费用索引
   */
  const handleSilometerChange = (index: number) => {
    const feeDetail = feeList.value[index]
    if (['undefined', 'null', ''].includes(`${feeDetail.kilometers}`.trim())) {
      feeList.value[index].kilometers = 0
    }

    const feeProject = feeProjectOptionList.value.find(
      (item) => item.id === feeDetail.workFeeProjectId,
    )

    if (feeProject.enableRemoteFees && !(feeDetail.networkUndertakePrice > 0)) {
      if (feeDetail.kilometers > 20) {
        feeDetail.networkUndertakePrice = (feeDetail.kilometers - 20) * 1.2
      }
    }
  }

  /**
   * 数量更新事件
   * @param feeIndex - 费用索引
   */
  const handleQtyChange = (index: number) => {
    const feeDetail = feeList.value[index]
    if (['undefined', 'null', ''].includes(`${feeDetail.qty}`.trim())) {
      feeList.value[index].qty = 1
    }
  }

  /**
   * (公司承担、收取客户、支付网点)费用更新事件
   * @param index - 费用索引
   */
  const handleFeeChange = (
    index: number,
    type: 'price' | 'customerUndertakePrice' | 'networkUndertakePrice',
  ) => {
    const feeDetail = feeList.value[index]
    if (['undefined', 'null', ''].includes(`${feeDetail[type]}`.trim())) {
      feeList.value[index][type] = 0
    }
  }
</script>

<style lang="scss" scoped>
  @import './FeeApplyCheckDialog.scss';
</style>
